package com.yenlien.traceyun.plant.dock_device;

import cn.hutool.http.HttpException;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.yenlien.traceyun.business.dao.BaseSoilEquipmentDao;
import com.yenlien.traceyun.business.dao.EquipmentDao;
import com.yenlien.traceyun.business.entity.Equipment;
import com.yenlien.traceyun.common.utils.Tools;
import com.yenlien.traceyun.plant.bean.DevDTO;
import com.yenlien.traceyun.plant.dao.*;
import com.yenlien.traceyun.plant.dock_device.sjrt.GetCWDevData;
import com.yenlien.traceyun.plant.dock_device.xinfengxiang.CurrentDataEntity;
import com.yenlien.traceyun.plant.entity.*;
import com.yenlien.traceyun.plant.utils.MathUtils;
import com.yenlien.traceyun.webase.exception.BusinessException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.*;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

import static com.yenlien.traceyun.plant.dock_device.sjrt.GetCWDevData.getNowDataUrl;
import static com.yenlien.traceyun.plant.utils.Tools.*;

/**
 * @Date 2023/10/16
 * @Descript 定时获取设备状态   二期果园数字乡村 时使用
 */

@Component
@Slf4j
public class DevState {

    @Autowired
    private EquipmentDao equipmentDao;
    @Autowired
    private SDRKDataDao sdrkDataDao;
    @Autowired
    private BaseSoilEquipmentDao baseSoilEquipmentDao;
    @Autowired
    private ShiJiRuiTongDao shiJiRuiTongDao;
    @Autowired
    private XinFengXiangDao xinFengXiangDao;
    @Autowired
    private OKQDataDao okqDataDao;
    @Autowired
    private DevThresholdDao devThresholdDao;
    @Autowired
    private DevAlarmDao devAlarmDao;
    @Autowired
    private FruitDataDao fruitDataDao;
    @Autowired
    private OKQEnvDataDao okqEnvDataDao;
    @Autowired
    private FruitDataConfigDao fruitDataConfigDao;
    @Value("${xinFengXiang.url}")
    private String url;


    public final static int ONE_HOURS = 1000 * 3600 * 1;

    public final static int TWO_HOURS = 1000 * 3600 * 2;

    public final static int FOUR_HOURS = 1000 * 3600 * 4;

    public final static int SIX_HOURS = 1000 * 3600 * 6;

    public final static int EIGHT_HOURS = 1000 * 3600 * 8;

    public final static int TEN_HOURS = 1000 * 3600 * 10;

    public static final String SJRT_GET_TOKEN = "http://open.agiot.sjrt.net/api/open/GetToken";

    public static final String EQU_MANUFACTURER_SJRT = "世纪瑞通";
    public static final String EQU_MANUFACTURER_XFX = "新风向";
    public static final String EQU_MANUFACTURER_KB = "科百";
    public static final String EQU_MANUFACTURER_SDRK = "山东仁科";
    public static final String EQU_MANUFACTURER_OKQ = "欧柯奇";


    public static final String EQU_TYPE_INSECT = "虫情监控";
    public static final String EQU_TYPE_KILL_INSECT = "杀虫灯";
    public static final String EQU_TYPE_ENV = "气象传感";
    public static final String EQU_TYPE_SOIL = "土壤墒情";
    public static final String EQU_TYPE_WATER = "水质设备";
    public static final String EQU_TYPE_VIDEO = "摄像机";

    public static final String EQU_TYPE_SOLENOID_VALVE = "电磁阀";
    public static final String EQU_TYPE_BIRD_REPELLENT = "驱鸟器";







    // 新风向获取设备状态  果园新风向设备  469076237   123123  http://47.105.215.208:8000/environment/login
    public static final String XFX_DEV_STATE = "http://47.105.215.208:8005/operation/statistics/onlone";

    public static final String SJRT_GET_ALL_DEV = "http://open.agiot.sjrt.net/api/open/GetDevList";

    public static final String YSY_GET_TOKEN = "https://open.ys7.com/api/lapp/token/get";

    public static final String SJRT_GET_VIDEO_URL = "http://open.agiot.sjrt.net/api/open/GetVideoData";

    public static final String YSY_GET_DEV_STATE = "https://open.ys7.com/api/v3/device/searchDeviceInfo";


    public static final String OKQ_GET_ALL_DEV = "http://nyzbwlw.com/situation/http/device/equipment/getEquipmentList";
    public static final String OKQ_GET_INSECT_DATA = "http://nyzbwlw.com/situation/http/device/bug/getBugData";

    public static final String OKQ_GET_WEATHER_DATA = "http://nyzbwlw.com/situation/http/device/weather/getWeatherList";

    public static final String OKQ_GET_KILL_INSECT_DATA = "http://nyzbwlw.com/situation/http/device/insect/getInsectDataList";



    public static final String SDRK_GET_TOKEN = "http://www.0531yun.com/api/getToken";

    public static final String SDRK_GET_DATA = "http://www.0531yun.com/api/data/getRealTimeDataByDeviceAddr";

    public static final String SDRK_GET_ALL_DEV = "http://www.0531yun.com/api/device/getDeviceList";


    // 世纪瑞通 设备
    public static Map<String, Map<String, String>> sjrtAppMap = new HashMap(){
        private static final long serialVersionUID = 8002935352497755397L;
        {
            Map<String, String> cwApp = new HashMap<>();
            cwApp.put("appId", "ecf95d7fb040f347");
            cwApp.put("appSecret", "de2e110eb1f32d07b3131223d8eddd41");
            put("4028814b89ae9d99018acf7d745c003d", cwApp);     // 长武/长凌

            Map<String, String> sfApp = new HashMap<>();
            sfApp.put("appId", "4e32653a9c801fdd");
            sfApp.put("appSecret", "de751f718e52cabfb315e21189fcf5e7");
            put("4028814b89ae9d99018acfe6d4060040", sfApp);               // 三丰

            Map<String, String> rjAPP = new HashMap<>();
            rjAPP.put("appId", "8a6a09254db4f4b4");
            rjAPP.put("appSecret", "e385773e0e7c6d60345b69d6ee8ae204");
            put("4028814b89ae9d99018acfe9b8ee0043", rjAPP);         // 瑞杰
    }};


    // 三丰与瑞杰共用一个萤石云账号
    public static Map<String, Map<String, String>> ysyAppMap = new HashMap(){
        private static final long serialVersionUID = -451093293655542229L;
        {
            Map<String, String> RJSFApp = new HashMap<>();    // 瑞杰和三丰公用一个AppId
            RJSFApp.put("appKey", "6f4f1f1c3ed04f58a4f140b5a997ef76");
            RJSFApp.put("appSecret", "cb5f4c3fdadd4804ec4418de783d0381");
            put("6f4f1f1c3ed04f58a4f140b5a997ef76", RJSFApp);

        }};

    public static Map<String, String> tokenMap = new HashMap();     // key=appId + companyId

    public static Map<String, Object> dataMap = new HashMap();     // key=equId  value=[]


    public static Map<String, List<Equipment>> devMap = new ConcurrentHashMap<>();
    // 视频设备
    public static Map<String, List<Equipment>> videoDevMap = new ConcurrentHashMap<>();

    // 保存山东仁科数据, 非果园二期时注释该方法
    @Scheduled(fixedRate = FOUR_HOURS, initialDelay = FOUR_HOURS)
    public void saveSDRKData() {
        sdrkDataDao.saveAll(reFreshGetSDRKDev(null));
    }


    @Scheduled(cron = "0 45 6 * * *")
    public void genPrice() {
        List<FruitDataConfig> fruitDataConfigList = fruitDataConfigDao.findAll();
        LocalDateTime now = LocalDateTime.now();
        String time = now.format(DATE_TIME_FORMATTER);
        for(FruitDataConfig dataConfig : fruitDataConfigList){
            if("2".equals(dataConfig.getType())){
                FruitData firstByType = fruitDataDao.getFirstByTypeAndVariety(dataConfig.getType(), dataConfig.getVariety());
                if(firstByType != null){
                    Period period = Period.between(LocalDateTime.parse(firstByType.getCreateTime(), DATE_TIME_FORMATTER).toLocalDate(), now.toLocalDate());
                    boolean isOneYearDifference = period.getYears() >= 1;
                    if(!isOneYearDifference)
                        continue;
                }
            }
            fruitDataDao.save(new FruitData(dataConfig.getVariety(), genRangeRandom(dataConfig.getMin(), dataConfig.getMax()), time, dataConfig.getType(),
                    "2".equals(dataConfig.getType()) ? "万吨" : "元"));
        }
    }



    // 保存 欧柯奇 数据 非果园二期时注释该方法
    @Scheduled(cron = "0 45 23 * * *")
    public void saveOKQData() {
        List<Equipment> equipmentList = equipmentDao.findByManufacturer(EQU_MANUFACTURER_OKQ);
        List<Equipment> insectList = equipmentList.stream().filter(x -> EQU_TYPE_INSECT.equals(x.getType())).collect(Collectors.toList());
        for(Equipment equipment : insectList){
            List<OKQData> okqDataList = getOkqDataList(equipment);
            for(OKQData okqData : okqDataList){
                okqData.setEquipmentId(equipment.getId());
                okqData.setEquipmentName(equipment.getName());
                okqData.setCompanyId(equipment.getCompanyId());
                okqData.setCTime(okqData.getCollectionTime());
                String massifId = baseSoilEquipmentDao.getMassifIdByEquId(equipment.getId());
                okqData.setBaseSoilId(massifId);
                okqData.setType("3");
                if("{}".equals(okqData.getPictureAnalysis()))
                    okqData.setPictureAnalysis(null);
                else {
                    String info = JSONObject.parseObject(okqData.getPictureAnalysis()).getString("info");
                    okqData.setPictureAnalysis(info);
                }
            }
//            okqDataDao.saveAll(okqDataList);
        }
        // 杀虫灯
        List<Equipment> killInsectList = equipmentList.stream().filter(x -> EQU_TYPE_KILL_INSECT.equals(x.getType())).collect(Collectors.toList());
        for(Equipment equipment : killInsectList){
            List<OKQData> okqDataList = getOkqKillInsectDataList(equipment);
            for(OKQData okqData : okqDataList){
                okqData.setEquipmentId(equipment.getId());
                okqData.setEquipmentName(equipment.getName());
                okqData.setCompanyId(equipment.getCompanyId());
                okqData.setCTime(okqData.getCollectionTime());
                String massifId = baseSoilEquipmentDao.getMassifIdByEquId(equipment.getId());
                okqData.setBaseSoilId(massifId);
                okqData.setType("5");
            }
            okqDataDao.saveAll(okqDataList);
        }
    }

    // 保存欧柯奇气象土壤数据
    @Scheduled(fixedRate = TEN_HOURS, initialDelay = TEN_HOURS)
//    @Scheduled(fixedRate = TEN_HOURS)
    public void saveOkqEnv(){
        List<Equipment> equipmentList = equipmentDao.findByManufacturer(EQU_MANUFACTURER_OKQ);
        // 欧柯奇土壤与气象（一个设备）
        List<Equipment> envList = equipmentList.stream().filter(x -> EQU_TYPE_ENV.equals(x.getType())).collect(Collectors.toList());
        for(Equipment env : envList){
            Map<String, Object> param2 = new HashMap<>();
            param2.put("deviceCode", env.getSerial());
            param2.put("startTime", LocalDate.now().minusDays(1).atTime(0, 0, 0).format(DATE_TIME_FORMATTER));
            param2.put("endTime", LocalDate.now().atTime(23, 59, 59).format(DATE_TIME_FORMATTER));
            //  10个小时获取一次数据
            JSONObject resultJson = JSONObject.parseObject(HttpUtil.get(OKQ_GET_WEATHER_DATA, param2));
            JSONArray jsonArray = resultJson.getJSONObject("data").getJSONArray("list");
            List<OKQENVData> envDataList = new ArrayList<>();
            for(Object o : jsonArray){
                JSONObject data = JSONObject.parseObject(o.toString());
                String collectionTime = data.getString("collectionTime");
                JSONArray weaTherList = data.getJSONArray("weaTherList");
                for(Object item : weaTherList){
                    JSONObject dataItem = JSONObject.parseObject(item.toString());
                    OKQENVData okqenvData = new OKQENVData();
                    okqenvData.setEquipmentId(env.getId());
                    okqenvData.setCTime(collectionTime);
                    okqenvData.setCompanyId(env.getCompanyId());
                    okqenvData.setDevId(env.getSerial());
                    okqenvData.setType("1");
                    String paramName = getParamName(dataItem.getString("name"));
                    if(paramName.contains("土壤水分")){
                        paramName.replace("土壤水分", "土壤湿度");
                    }
                    okqenvData.setParamName(paramName);
                    okqenvData.setParamUnit(getParamUnit(dataItem.getString("name")));
                    okqenvData.setParamVal(dataItem.getString("value"));
                    envDataList.add(okqenvData);
                }
            }
            okqEnvDataDao.saveAll(envDataList);
        }
    }





    // 15 分钟刷新一次设备列表·
    @Scheduled(fixedRate = 1000 * 60 * 60)
    public void reFreshDevState() {
        List<Equipment> equipmentList = equipmentDao.findAll().stream().filter(x -> StringUtils.isNotBlank(x.getAppKey())).collect(Collectors.toList());

        reFreshSJRTDev(equipmentList.stream().filter(x -> EQU_MANUFACTURER_SJRT.equals(x.getManufacturer())).filter(x -> {
                    if("4028814b89ae9d99018acf7d745c003d".equals(x.getCompanyId())){
                        return true;
                    }else if(EQU_TYPE_VIDEO.equals(x.getType())){    // 非长武项目的摄像机不返回(长武项目摄像机厂商是世纪瑞通)
                        return false;
                    }else
                        return true;
                }
        ).collect(Collectors.toList()));

        reFreshXFXDev(equipmentList.stream().filter(x -> EQU_MANUFACTURER_XFX.equals(x.getManufacturer())).collect(Collectors.toList()));
        reFreshGetSDRKDev(equipmentList.stream().filter(x -> EQU_MANUFACTURER_SDRK.equals(x.getManufacturer())).collect(Collectors.toList()));
        reFreshOKQ(equipmentList.stream().filter(x -> EQU_MANUFACTURER_OKQ.equals(x.getManufacturer())).collect(Collectors.toList()));

        // 没有得到状态则认为离线
        LocalDateTime now = LocalDateTime.now();
        for(String compId : devMap.keySet()){
            List<Equipment> devList = devMap.get(compId);
            for(Equipment equ : devList){
                if(StringUtils.isBlank(equ.getStatus()) || "0".equals(equ.getStatus())){
                    equ.setStatus("0");
                    equ.setHeartbeatTime("无");
                    equ.setPurchaseTime(equ.getHeartbeatTime());
                }else {
                    if("1".equals(equ.getStatus())){
                        String time = StringUtils.isBlank(equ.getHeartbeatTime()) ? now.format(DATE_TIME_FORMATTER) : equ.getHeartbeatTime();
                        equ.setHeartbeatTime(time);
                        equ.setPurchaseTime(time);
                    }
                }
            }
        }
    }




    @Scheduled(fixedRate = 1000 * 60 * 30)
    public void reFreshVideoDevState() {
        List<Equipment> videoList = equipmentDao.findByType(EQU_TYPE_VIDEO);
        reFreshYSY(videoList.stream().filter(x -> "萤石云".equals(x.getManufacturer())).collect(Collectors.toList()));

    }




    public void reFreshYSY(List<Equipment> videoList){
        List<Equipment> videoEquList = new ArrayList<>();
        Map<String, List<Equipment>> keyMapList = videoList.stream().collect(Collectors.groupingBy(Equipment::getAppKey));
        LocalDateTime now = LocalDateTime.now();
        for(String appKey : keyMapList.keySet()){
            LocalDateTime time;
            List<Equipment> equList = keyMapList.get(appKey);
            Equipment videoEqu = equList.get(0);
            String ysyToken;
            try {
                ysyToken = getYSYToken(appKey, videoEqu.getAppSecret());
            }catch (Exception e){
                log.error("获取萤石云token失败, appKey: {}", appKey, e.getCause() == null ? e.getMessage() : e.getCause().toString());
                continue;
            }
            Map<String, List<Equipment>> equListMap = equList.stream().collect(Collectors.groupingBy(Equipment::getSerial));    // 一个序列号下的通道要么都在线要么都不在线
            for(String serial : equListMap.keySet()){
                String state;
                try {
                    state = getYSYDevState(ysyToken, serial);
                }catch (Exception e){
                    log.error("获取萤石云设备状态失败, serial设备序列号: {}, msg: {}", serial, e.getCause() == null ? e.getMessage() : e.getCause().toString());
                    continue;
                }
                List<Equipment> equipmentList = equListMap.get(serial);
                for(Equipment equipment : equipmentList){
                    equipment.setStatus(state);
                    if("1".equals(state)){
                        time = now.minusHours(1);
                        equipment.setHeartbeatTime(time.format(DATE_TIME_FORMATTER));
                    }else {
                        equipment.setHeartbeatTime("无");
                    }
                    equipment.setPurchaseTime(equipment.getHeartbeatTime());
                    videoEquList.add(equipment);
                }
            }
        }
        for(Equipment equipment : videoEquList){
            if(StringUtils.isBlank(equipment.getStatus())){
                equipment.setStatus("0");
                equipment.setHeartbeatTime("无");
                equipment.setPurchaseTime(equipment.getHeartbeatTime());
            }
        }
        Map<String, List<Equipment>> listMap = videoEquList.stream().collect(Collectors.groupingBy(Equipment::getCompanyId));
        for(String companyId : listMap.keySet()){
            videoDevMap.put(companyId, listMap.get(companyId));
        }
//        for(String key : ysyAppMap.keySet()){
//            Map<String, String> map = ysyAppMap.get(key);
//            String ysyToken = getYSYToken(map.get("appKey"), map.get("appSecret"));
//            Map<String, List<Equipment>> equListMap = equipmentDao.findByAppKey(key).stream().collect(Collectors.groupingBy(Equipment::getSerial));
//            for(String serial : equListMap.keySet()){
//                String state = getYSYDevState(ysyToken, serial);
//                List<Equipment> equipmentList = equListMap.get(serial);
//                for(Equipment equipment : equipmentList){
//                    equipment.setStatus(state);
//                    videoEquList.add(equipment);
//                }
//            }
//        }
//        Map<String, List<Equipment>> listMap = videoEquList.stream().collect(Collectors.groupingBy(Equipment::getCompanyId));
//        for(String companyId : listMap.keySet()){
//            videoDevMap.put(companyId, listMap.get(companyId));
//        }
    }


    public String genRangeRandom(double minValue, double maxValue){
        Random random = new Random();
        double range = maxValue - minValue;
        List<Double> doubles = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            doubles.add(random.nextDouble() * range + minValue);
        }
        return MathUtils.formatOne(doubles.stream().mapToDouble(Double::valueOf).summaryStatistics().getAverage());
    }

    // 刷新 欧可奇设备状态
    public void reFreshOKQ(List<Equipment> equipmentList){
        List<Equipment> allInsectList = new ArrayList<>();
        Map<String, List<Equipment>> keyMapList = equipmentList.stream().collect(Collectors.groupingBy(Equipment::getAppKey));
        LocalDateTime now = LocalDateTime.now();
        for(String appKey : keyMapList.keySet()){
            List<Equipment> equList = keyMapList.get(appKey);
            Equipment insectEqu = equList.get(0);
            JSONArray jsonArray;
            try {
                jsonArray = getOkqDevList(insectEqu);
            }catch (BusinessException e){
                log.error(e.getMsg());
                continue;
            }
            for(Object obj : jsonArray){
                JSONObject dev = JSONObject.parseObject(obj.toString());
                for(Equipment equ : equList){
                    if(dev.getString("code").equals(equ.getSerial())){
                        equ.setStatus("在线".equals(dev.getString("status")) ? "1" : "0");
                        break;
                    }
                }
            }
            for(Equipment equ : equList){
                if(StringUtils.isBlank(equ.getStatus())){
                    equ.setStatus("1");
                }
                LocalDateTime heartbeatTime;
                if("0".equals(equ.getStatus())){
                    // 离线预警
                    if(CollectionUtils.isEmpty(devAlarmDao.getAlarmByDevId(equ.getSerial()))){
                        DevAlarm devAlarm = new DevAlarm();
                        devAlarm.setAlarmType("2");
                        devAlarm.setDevId(equ.getSerial());
                        devAlarm.setDevName(equ.getName());
                        devAlarm.setTitle("已离线");
                        devAlarm.setDevType(equ.getType());
                        devAlarm.setCreateTime(DATE_TIME_FORMATTER.format(now));
                        devAlarm.setCompId(equ.getCompanyId());
                        devAlarm.setHandleState("1");
                        devAlarmDao.save(devAlarm);
                    }
                    heartbeatTime = now.minusDays(1);
                    equ.setHeartbeatTime("无");
                } else{
                    heartbeatTime = now.minusHours(1);
                    equ.setHeartbeatTime(heartbeatTime.format(DATE_TIME_FORMATTER));
                }
                equ.setPurchaseTime(equ.getHeartbeatTime());
            }
            allInsectList.addAll(equList);
        }
        Map<String, List<Equipment>> compIdMapList = allInsectList.stream().collect(Collectors.groupingBy(Equipment::getCompanyId));
        for(String compId : compIdMapList.keySet()){
            List<Equipment> devList = compIdMapList.get(compId);
            List<Equipment> otherDevList = devMap.get(compId);
            if(CollectionUtils.isNotEmpty(otherDevList)){
                devList.addAll(otherDevList.stream().filter(x -> !EQU_MANUFACTURER_OKQ.equals(x.getManufacturer())).collect(Collectors.toList()));
            }
            devMap.put(compId, devList);
        }
    }




    // 刷新世纪瑞通设备
    public void reFreshSJRTDev(List<Equipment> equipmentList) {
//    public void reFreshSJRTDev() {
        Map<String, List<Equipment>> equListMap = equipmentList.stream().collect(Collectors.groupingBy(Equipment::getAppKey));
        ArrayList<Equipment> allEquList = new ArrayList<>();
        LocalDateTime now = LocalDateTime.now();
        for(String appKey : equListMap.keySet()){
            List<Equipment> equList = equListMap.get(appKey);
            Equipment equipment = equList.get(0);
            String companyId = equipment.getCompanyId();
            String token = getSJRTToken(appKey, equipment.getAppSecret());
            if(StringUtils.isBlank(token))
                continue;
            tokenMap.put(appKey + equipment.getCompanyId(), token);
            List<DevDTO> dtoList = getDevState(getAllDev(token));
            equList = devToEqu(dtoList, equList);
            for(Equipment equ : equList){
                // 将气象/土壤/水质设备数据写入缓存
                if(EQU_TYPE_ENV.equals(equ.getType()) || EQU_TYPE_SOIL.equals(equ.getType()) || EQU_TYPE_WATER.equals(equ.getType())){
                    // 从本地获取
                    dataMap.put(equ.getId(), shiJiRuiTongDao.getLast(equ.getId()));

                    // 从对方平台获取最新（世纪瑞通设备返回的数据有问题）
//                    dataMap.put(equ.getId(), getSJRTNowData(equipment.getSerial(), token));
                }
                // 没有拿到是否离线则写成在线
                if(StringUtils.isBlank(equ.getStatus()))
                    equ.setStatus("1");
                if("0".equals(equ.getStatus())){
                    if(CollectionUtils.isEmpty(devAlarmDao.getAlarmByDevId(equ.getSerial()))){
                        DevAlarm devAlarm = new DevAlarm();
                        devAlarm.setAlarmType("2");
                        devAlarm.setDevId(equ.getSerial());
                        devAlarm.setDevName(equ.getName());
                        devAlarm.setTitle("已离线");
                        devAlarm.setDevType(equ.getType());
                        devAlarm.setCreateTime(DATE_TIME_FORMATTER.format(now));
                        devAlarm.setCompId(equ.getCompanyId());
                        devAlarm.setHandleState("1");
                        devAlarmDao.save(devAlarm);
                    }
                }
            }
            allEquList.addAll(equList);
        }

        Map<String, List<Equipment>> compIdMapList = allEquList.stream().collect(Collectors.groupingBy(Equipment::getCompanyId));
        for(String compId : compIdMapList.keySet()){
            List<Equipment> devList = compIdMapList.get(compId);
            // 不能覆盖其他厂商的设备
            List<Equipment> otherDevList = devMap.get(compId);
            if(CollectionUtils.isNotEmpty(otherDevList)){
                devList.addAll(otherDevList.stream().filter(x -> !EQU_MANUFACTURER_SJRT.equals(x.getManufacturer())).collect(Collectors.toList()));
            }
            // 长凌的视频设备也是用的世纪瑞通，这种情况就把视频设备拿出来放到 videoDevMap
            if("4028814b89ae9d99018acf7d745c003d".equals(compId)){
                videoDevMap.put(compId, devList.stream().filter(x -> EQU_TYPE_VIDEO.equals(x.getType())).collect(Collectors.toList()));   // 直接覆盖
                devMap.put(compId, devList.stream().filter(x -> !EQU_TYPE_VIDEO.equals(x.getType())).collect(Collectors.toList()));
            }else
                devMap.put(compId, devList);
        }

        // 直接从世纪瑞通平台获取设备的方式
//        for(String companyId : sjrtAppMap.keySet()){
//            Map<String, String> map = sjrtAppMap.get(companyId);
//            String token = getToken(map.get("appId"), map.get("appSecret"));
//            if(StringUtils.isBlank(token))
//                continue;
//            tokenMap.put(map.get("appId") + companyId, token);
//            List<DevDTO> dtoList = getDevState(getAllDev(token));
//            List<Equipment> equipmentList = devToEqu(dtoList, equipmentDao.findBySerialList(dtoList.stream().map(DevDTO::getDevId).collect(Collectors.toList()), companyId));
//            // 长凌的视频设备也是用的世纪瑞通，这种情况就把视频设备拿出来放到 videoDevMap
//            if("4028814b89ae9d99018acf7d745c003d".equals(companyId)){
//                List<Equipment> videoList = equipmentList.stream().filter(x -> EQU_TYPE_VIDEO.equals(x.getType())).collect(Collectors.toList());
//                List<Equipment> equList = equipmentList.stream().filter(x -> !EQU_TYPE_VIDEO.equals(x.getType())).collect(Collectors.toList());
//                videoDevMap.put(companyId, videoList);   // 直接覆盖
//                devMap.put(companyId, equList);
//            }else
//                devMap.put(companyId, equipmentList);
//        }
    }


    // 刷新新风向设备
    public void reFreshXFXDev(List<Equipment> xFXEquList) {
        // 新风向设备
        if(CollectionUtils.isEmpty(xFXEquList))
            return;
        Map<String, List<Equipment>> xFXMapList = xFXEquList.stream().collect(Collectors.groupingBy(Equipment::getAppKey));
        List<Equipment> allEquList = new ArrayList<>();
        LocalDateTime now = LocalDateTime.now();
        for(String xFXKey : xFXMapList.keySet()){
            List<Equipment> equipmentList = xFXMapList.get(xFXKey);
            JSONArray jsonArray = null;
            try {
                jsonArray = JSONObject.parseArray(HttpUtil.get(XFX_DEV_STATE + "?username=" + xFXKey));
                JSONObject devJSON = jsonArray.getJSONObject(jsonArray.size() - 1).getJSONObject("device");
                List<String> onlineDevices = JSONObject.parseArray(devJSON.getString("onlineDevices"), String.class);
                List<String> offlineDevices = JSONObject.parseArray(devJSON.getString("offlineDevices"), String.class);
                for(Equipment equipment : equipmentList){
                    LocalDateTime time;
                    if(onlineDevices.contains(equipment.getSerial())){
                        equipment.setStatus("1");
                        time = now.minusMinutes(17);
                        equipment.setHeartbeatTime(time.format(DATE_TIME_FORMATTER));
                    }else if(offlineDevices.contains(equipment.getSerial())){
                        equipment.setStatus("0");
                        // 离线预警
                        if(CollectionUtils.isEmpty(devAlarmDao.getAlarmByDevId(equipment.getSerial()))){
                            DevAlarm devAlarm = new DevAlarm();
                            devAlarm.setAlarmType("2");
                            devAlarm.setDevId(equipment.getSerial());
                            devAlarm.setDevName(equipment.getName());
                            devAlarm.setTitle("已离线");
                            devAlarm.setDevType(equipment.getType());
                            devAlarm.setCreateTime(DATE_TIME_FORMATTER.format(now));
                            devAlarm.setCompId(equipment.getCompanyId());
                            devAlarm.setHandleState("1");
                            devAlarmDao.save(devAlarm);
                        }
                        equipment.setHeartbeatTime("无");
                    }else{
                        equipment.setStatus("1");   // 拿不到状态则认为在线
                        time = now.minusHours(1);
                        equipment.setHeartbeatTime(time.format(DATE_TIME_FORMATTER));
                    }
                    equipment.setPurchaseTime(equipment.getHeartbeatTime());
                }
            }catch (Exception e){

            }
            if(CollectionUtils.isEmpty(jsonArray)){
                for(Equipment equipment : equipmentList)
                    equipment.setStatus("0");
            }
            allEquList.addAll(equipmentList);
        }
        Map<String, List<Equipment>> compIdMapList = allEquList.stream().collect(Collectors.groupingBy(Equipment::getCompanyId));
        for(String compId : compIdMapList.keySet()){
            List<Equipment> devList = compIdMapList.get(compId);
            //当一个企业使用了多个厂商的设备  时需要注意防止覆盖
//            if("4028814b89ae9d99018ab088f43b0032".equals(compId)){
//                List<Equipment> equipmentList = devMap.get(compId);
//                if(CollectionUtils.isNotEmpty(equipmentList)){
//                    equipmentList = equipmentList.stream().filter(x -> !EQU_MANUFACTURER_XFX.equals(x.getManufacturer())).collect(Collectors.toList());
//                    devList.addAll(equipmentList);
//                }
//            }
            // 不能覆盖其他厂商的设备
            List<Equipment> otherDevList = devMap.get(compId);
            if(CollectionUtils.isNotEmpty(otherDevList)){
                devList.addAll(otherDevList.stream().filter(x -> !EQU_MANUFACTURER_XFX.equals(x.getManufacturer())).collect(Collectors.toList()));
            }

            devMap.put(compId, devList);
        }
        // 将气象/土壤/水质设备数据写入缓存
        for(Equipment equ : allEquList){
            if(EQU_TYPE_ENV.equals(equ.getType()) || EQU_TYPE_SOIL.equals(equ.getType()) || EQU_TYPE_WATER.equals(equ.getType())){
                // 从本地获取
                dataMap.put(equ.getId(), xinFengXiangDao.getLast(equ.getId()));
                 // 从对方平台获取最新（世纪瑞通设备返回的数据有问题）
//                dataMap.put(equ.getId(), XFXConvter2SJRT(getXFXNowData(equ.getSerial())));
            }
        }
    }

    // 山东仁科设备状态刷新并获取数据
    public List<SDRKData> reFreshGetSDRKDev(List<Equipment> sDRKEquList) {
        // 新风向设备
        if(CollectionUtils.isEmpty(sDRKEquList))
            sDRKEquList = equipmentDao.findByManufacturer(EQU_MANUFACTURER_SDRK);
        if(CollectionUtils.isEmpty(sDRKEquList))
            return null;
        Map<String, List<Equipment>> keyMapList = sDRKEquList.stream().collect(Collectors.groupingBy(Equipment::getAppKey));
        List<Equipment> allEquList = new ArrayList<>();
        List<SDRKData> dataList = new ArrayList<>();
        Date date = new Date();
        List<DevAlarm> alarmList = new ArrayList<>();
        for(String appkey : keyMapList.keySet()){
            List<Equipment> equipmentList = keyMapList.get(appkey);
            Equipment equipment = equipmentList.get(0);
            String token = getSDRKToken(equipment.getAppKey(), equipment.getAppSecret());
            if(StringUtils.isBlank(token))
                continue;
            tokenMap.put(appkey + equipment.getCompanyId(), token);
            Map<String, Object> map = new HashMap<>();
            map.put("deviceAddrs", equipmentList.stream().map(Equipment::getSerial).collect(Collectors.joining(",")));
            JSONArray jsonArray = new JSONArray();
            try {
                jsonArray = JSONObject.parseObject(HttpUtil.createGet(SDRK_GET_DATA).header("authorization", token).form(map).execute().body()).getJSONArray("data");
            }catch (Exception e){
                log.error("山东仁科请求数据失败");
            }
            List<SDRKData> sdrkDataList = new ArrayList<>();
            for(Object obj : jsonArray){
                JSONObject json = JSONObject.parseObject(obj.toString());
                String deviceStatus = json.getString("deviceStatus");
                String devAddr = json.getString("deviceAddr");      // 设备序列号
                List<DevThreshold> devThresholdList = devThresholdDao.getByCompIdAndEquId(equipment.getCompanyId(), devAddr);
                String time = DATE_TIME_FORMATTER.format(Instant.ofEpochMilli(json.getLong("timeStamp")).atZone(ZoneOffset.ofHours(8)).toLocalDateTime());
                String status = "normal".equals(deviceStatus) ? "1" : "offline".equals(deviceStatus) ? "0" : "alarming".equals(deviceStatus) ? "2" : "3";
                if(StringUtils.isBlank(status))
                    status = "1";
                // 匹配设备状态
                Equipment nowEqu = null;
                for(Equipment equ : equipmentList){
                    if(equ.getSerial().equals(devAddr)){
                        nowEqu = equ;
                        equ.setStatus(status);
                        LocalDateTime heartbeatTime;
                        if ("0".equals(equ.getStatus())) {
                            equ.setHeartbeatTime("无");
                            if (CollectionUtils.isEmpty(devAlarmDao.getAlarmByDevId(nowEqu.getSerial()))) {
                                DevAlarm devAlarm = new DevAlarm();
                                devAlarm.setAlarmType("2");
                                devAlarm.setDevId(nowEqu.getSerial());
                                devAlarm.setDevName(nowEqu.getName());
                                devAlarm.setTitle("已离线");
                                devAlarm.setDevType(nowEqu.getType());
                                devAlarm.setCreateTime(DATE_TIME_FORMAT.format(date));
                                devAlarm.setCompId(nowEqu.getCompanyId());
                                devAlarm.setHandleState("1");
                                devAlarmDao.save(devAlarm);
                            }
                        } else if("1".equals(equ.getStatus())){
                            heartbeatTime = LocalDateTime.now().minusMinutes(20);
                            equ.setHeartbeatTime(heartbeatTime.format(DATE_TIME_FORMATTER));
                        }
                        equ.setPurchaseTime(equ.getHeartbeatTime());
                        break;
                    }
                }
                if(nowEqu == null)
                    continue;
                // 获取地块ID  牛王村没有配套地块
//                String massifId = baseSoilEquipmentDao.getMassifIdByEquId(nowEqu.getId());
                JSONArray dataItem = json.getJSONArray("dataItem");
                if(dataItem == null)
                    continue;
                for(Object item : dataItem){
                    JSONObject dataItemJson = JSONObject.parseObject(item.toString());
                    JSONArray registerItem = dataItemJson.getJSONArray("registerItem");
                    ArrayList<SDRKData> oneDataList = new ArrayList<>();
                    for(Object itemObj : registerItem){
                        JSONObject object = JSONObject.parseObject(itemObj.toString());
                        String registerName = object.getString("registerName");
                        Float val = object.getFloat("data");
                        String unit = object.getString("unit");
                        SDRKData sdrkData = new SDRKData();
                        sdrkData.setParamUnit(unit);
                        sdrkData.setEquipmentId(nowEqu.getId());
                        sdrkData.setEquipmentName(nowEqu.getName());
                        sdrkData.setCompanyId(nowEqu.getCompanyId());
//                        sdrkData.setBaseSoilId(massifId);
                        sdrkData.setParamVal(val);
                        sdrkData.setParamName(registerName);
                        sdrkData.setCtime(time);
                        sdrkData.setType("1");
                        dataList.add(sdrkData);
                        // 添加阈值
                        if(CollectionUtils.isNotEmpty(sDRKEquList)){
                            List<DevThreshold> thresholdList = devThresholdList.stream().filter(x -> x.getType().equals(registerName)).collect(Collectors.toList());
                            if(CollectionUtils.isNotEmpty(thresholdList)){
                                DevThreshold devThreshold = thresholdList.get(0);
                                if(devThreshold != null){
                                    Double high = devThreshold.getHigh();
                                    Double low = devThreshold.getLow();
                                    if(val > high || val < low){
                                        DevAlarm devAlarm = new DevAlarm();
                                        devAlarm.setDevId(nowEqu.getSerial());
                                        devAlarm.setDevName(nowEqu.getName());
                                        devAlarm.setDevType(nowEqu.getType());
                                        devAlarm.setParamName(registerName);
                                        devAlarm.setVal(String.valueOf(val));
                                        devAlarm.setThreshold(low + unit + "~" + high + unit);
                                        devAlarm.setCompId(nowEqu.getCompanyId());
                                        devAlarm.setHandleState("1");
                                        devAlarm.setBaseSoilName(nowEqu.getName());
                                        devAlarm.setCreateTime(Tools.DATE_TIME_FORMAT.format(date));
                                        devAlarm.setAlarmType("1");
                                        if(val > high)
                                            devAlarm.setTitle(registerName + "高于最大值: " + high);
                                        if(val < low)
                                            devAlarm.setTitle(registerName + "低于最小值: " + low);
                                        if(CollectionUtils.isEmpty(devAlarmDao.getIdByParamNameAndDevId(registerName, nowEqu.getSerial()))){
                                            alarmList.add(devAlarm);
                                        }
                                    }
                                }
                            }
                        }
                        sdrkDataList.add(sdrkData);
                        oneDataList.add(sdrkData);
                    }
                    dataMap.put(nowEqu.getId(), oneDataList);
                }
            }
            allEquList.addAll(equipmentList);
        }
        devAlarmDao.saveAll(alarmList);
        Map<String, List<Equipment>> compIdMapList = allEquList.stream().collect(Collectors.groupingBy(Equipment::getCompanyId));
        for(String compId : compIdMapList.keySet()){
            List<Equipment> devList = compIdMapList.get(compId);
            List<Equipment> otherDevList = devMap.get(compId);
            if(CollectionUtils.isNotEmpty(otherDevList)){
                devList.addAll(otherDevList.stream().filter(x -> !EQU_MANUFACTURER_SDRK.equals(x.getManufacturer())).collect(Collectors.toList()));
            }
            devMap.put(compId, devList);
        }
        return dataList;
    }








    public static void main(String[] args) {



//        Map<String, Object> param = new HashMap<>();
//        param.put("userName", "chx");
//        param.put("passWord", "123456");
//        JSONArray jsonArray;
//        try {
//            JSONObject jsonObject = JSONObject.parseObject(HttpUtil.get(OKQ_GET_ALL_DEV, param));
//            if(100 != jsonObject.getInteger("code")){
//                throw new BusinessException(jsonObject.getString("msg"));
//            }
//            jsonArray = jsonObject.getJSONObject("data").getJSONArray("list");
//            jsonArray.forEach(x -> System.out.println(x));
//        }catch (HttpException e){
//        }catch (JSONException e){
//        }
    }

    public static String getParamName(String name){
        if("空气温度1".equals(name))
            return "大气温度";
        if("空气湿度1".equals(name))
            return "大气湿度";
        if("光照".equals(name))
            return "光照强度";
        if("风向Num".equals(name))
            return "风向";
        if("风向".equals(name))
            return "风向值";
        if("雨量".equals(name))
            return "降雨量";
        if("土壤温度1".equals(name))
            return "土壤温度10cm";
        if("土壤水分1".equals(name))
            return "土壤水分10cm";
        if("土壤水分2".equals(name))
            return "土壤水分20cm";
        if("土壤温度2".equals(name))
            return "土壤温度20cm";
        if("土壤温度3".equals(name))
            return "土壤温度30cm";
        if("土壤水分3".equals(name))
            return "土壤水分30cm";
        if("土壤温度4".equals(name))
            return "土壤温度40cm";
        if("土壤水分4".equals(name))
            return "土壤水分40cm";
        if("土壤温度5".equals(name))
            return "土壤温度50cm";
        else
            return name;
    }

    public static String getParamUnit(String name){
        if("空气温度1".equals(name))
            return "℃";
        if("空气湿度1".equals(name))
            return "%";
        if("光照".equals(name))
            return "lux";
        if("风向Num".equals(name))
            return "°";
        if("风速".equals(name))
            return "m/s";
        if("雨量".equals(name))
            return "mm";
        if("土壤温度1".equals(name))
            return "℃";
        if("土壤水分1".equals(name))
            return "%";
        if("大气压".equals(name))
            return "hPa";
        if("土壤温度2".equals(name))
            return "℃";
        if("土壤水分2".equals(name))
            return "%";
        if("土壤温度3".equals(name))
            return "℃";
        if("土壤水分3".equals(name))
            return "%";
        if("土壤温度4".equals(name))
            return "℃";
        if("土壤水分4".equals(name))
            return "%";
        if("土壤氧气".equals(name))
            return "%";
        if("土壤温度5".equals(name))
            return "℃";
        else
            return "";
    }

    public JSONArray getOkqDevList(Equipment insectEqu){
        Map<String, Object> param = new HashMap<>();
        param.put("userName", insectEqu.getAppKey());
        param.put("passWord", insectEqu.getAppSecret());
        JSONArray jsonArray;
        try {
            JSONObject jsonObject = JSONObject.parseObject(HttpUtil.get(OKQ_GET_ALL_DEV, param));
            if(100 != jsonObject.getInteger("code")){
                throw new BusinessException(jsonObject.getString("msg"));
            }
            jsonArray = jsonObject.getJSONObject("data").getJSONArray("list");
        }catch (HttpException e){
            log.error("获取欧柯奇设备列表失败, userName: {}, error: {}", insectEqu.getAppKey(), e.getCause() == null ? e.getMessage() : e.getCause().toString());
            throw new BusinessException("获取欧柯奇设备列表失败, error: 网络异常, userName: " + insectEqu.getAppKey());
        }catch (JSONException e){
            log.error("获取欧柯奇设备列表失败, userName: {}, error: {}", insectEqu.getAppKey(), "JSON格式异常");
            throw new BusinessException("获取欧柯奇设备列表失败, error: JSON格式异常, userName: " + insectEqu.getAppKey());
        }
        return jsonArray;
    }



    public List<OKQData> getOkqDataList(Equipment insectEqu){
        Map<String, Object> param = new HashMap<>();
        param.put("deviceCode", insectEqu.getSerial());
        param.put("startTime", LocalDate.now().minusDays(1).atTime(0, 0, 0).format(DATE_TIME_FORMATTER));
        param.put("endTime", LocalDate.now().atTime(23, 59, 59).format(DATE_TIME_FORMATTER));
        JSONObject resultJson = JSONObject.parseObject(HttpUtil.get(OKQ_GET_INSECT_DATA, param));
        return JSONObject.parseArray(resultJson.getJSONObject("data").getString("list"), OKQData.class);
    }

    public List<OKQData> getOkqKillInsectDataList(Equipment killInsectEqu){
        Map<String, Object> param = new HashMap<>();
        param.put("deviceCode", killInsectEqu.getSerial());
//        param.put("startTime", LocalDate.now().minusDays(1).atTime(0, 0, 0).format(DATE_TIME_FORMATTER));
//        param.put("endTime", LocalDate.now().atTime(23, 59, 59).format(DATE_TIME_FORMATTER));
        JSONObject resultJson = JSONObject.parseObject(HttpUtil.get(OKQ_GET_KILL_INSECT_DATA, param));
        return JSONObject.parseArray(resultJson.getJSONObject("data").getString("list"), OKQData.class);
    }

    public static List<ShiJiRuiTong> getSJRTNowData(String devId, String token) {
        Map<String, String> param = new HashMap<>();
        param.put("DevId", devId);
        String result = HttpRequest.post(getNowDataUrl).body(JSONObject.toJSONString(param))
                .header("Authorization", "Bearer " + token).execute().body();
        boolean isSuccess = JSONObject.parseObject(result).getBoolean("IsSuccess");
        if (isSuccess) {
            return JSONObject.parseArray(JSONObject.parseObject(result).getString("Data"), ShiJiRuiTong.class);
        } else {
            throw new BusinessException(JSONObject.parseObject(result).getString("Msg"));
        }
    }

    public List<CurrentDataEntity> getXFXNowData(String devId) {
        JSONObject result = JSONObject.parseObject(HttpUtil.get(url + devId));     // 获取数据并解析
        List<CurrentDataEntity> lists = new ArrayList<>();
        if (result == null) {
            return lists;
        }
        if ("200".equals(result.get("statusCode")) && "success".equals(result.get("message"))) {
            JSONArray jsonArray = result.getJSONArray("entity");
            if (jsonArray == null || jsonArray.size() == 0) {
                log.error("该序列号对应的设备在新风向平台不存在, 序列号: {}", devId);
                return lists;
            }
            jsonArray.forEach(item -> lists.add(JSON.parseObject(item.toString(), CurrentDataEntity.class)));
        }
        return lists;
    }


    public static List<ShiJiRuiTong> XFXConvter2SJRT(List<CurrentDataEntity> dataList){
        List<ShiJiRuiTong> shiJiRuiTongList = new ArrayList<>();
        for(CurrentDataEntity data : dataList){
            ShiJiRuiTong shiJiRuiTong = new ShiJiRuiTong();
            shiJiRuiTong.setParamName(data.getEName());
            shiJiRuiTong.setParamVal(data.getEValue());
            shiJiRuiTong.setParamUnit(data.getEUnit());
            shiJiRuiTong.setCtime(DATE_TIME_FORMAT.format(data.getDatetime()));
            shiJiRuiTongList.add(shiJiRuiTong);
        }
        return shiJiRuiTongList;
    }







    public static  String getYSYToken(String appKye, String appSecret){
        JSONObject param = new JSONObject();
        param.put("appKey", appKye);
        param.put("appSecret", appSecret);
        String post = HttpUtil.post(YSY_GET_TOKEN, param);
        String token = "";
        JSONObject result = JSONObject.parseObject(post);
        if("200".equals(result.getString("code")))
            token = result.getJSONObject("data").getString("accessToken");
        return token;
    }

    public static String getYSYDevState(String token, String deviceSerial){
        JSONObject param = new JSONObject();
        param.put("accessToken", token);
        param.put("deviceSerial", deviceSerial);
        JSONObject result;
        String status;
        try {
            String post = HttpUtil.post(YSY_GET_DEV_STATE, param);
            result = JSONObject.parseObject(post);
            status = result.getJSONObject("result").getJSONObject("data").getString("status"); // 1-在线，0-不在线
            if("200".equals(result.getJSONObject("result").getString("code")))
                throw new BusinessException(result.getString("msg"));
        }catch (HttpException e){
            throw new BusinessException("网络异常");
        }catch (JSONException e){
            throw new BusinessException("JSON格式异常");
        }
        return status;
    }



    // 世纪瑞通设备获取Token
    public static String getSJRTToken(String appId, String appSecret) {
        Map<String, String> loginParam = new HashMap<>();
        loginParam.put("AppId", appId);
        loginParam.put("AppSecret", appSecret);
        String result = HttpUtil.post(SJRT_GET_TOKEN, JSONObject.toJSONString(loginParam));
        boolean isSuccess = JSONObject.parseObject(result).getBoolean("IsSuccess");
        if (isSuccess) {
            return JSONObject.parseObject(result).getJSONObject("Data").getString("Token");
        } else {
            log.error("获取Token失败, AppId为: {}", appId);
            return "";
        }
    }


    // 山东仁科设备获取Token
    public static String getSDRKToken(String loginName, String password) {
        Map<String, Object> param = new HashMap<>();
        param.put("loginName", loginName);
        param.put("password", password);
        String token = null;
        try {
            token = JSONObject.parseObject(HttpUtil.get(SDRK_GET_TOKEN, param)).getJSONObject("data").getString("token");
        }catch (Exception e){
            log.error("获取SDRK Token失败, loginName为: {}", loginName);
        }
        return token;
    }


    // paramStr 为设备序列号(deviceAddr) 多个使用 , 分隔
    public static JSONObject getSDRKData(String token, String paramStr, List<Equipment> equipmentList) {
        Map<String, Object> map = new HashMap<>();
        if(CollectionUtils.isEmpty(equipmentList))
            map.put("deviceAddrs", paramStr);
        else
            map.put("deviceAddrs", equipmentList.stream().map(Equipment::getSerial).collect(Collectors.joining(",")));
        JSONArray jsonArray = JSONObject.parseObject(HttpUtil.createGet(SDRK_GET_DATA).header("authorization", token).form(map).execute().body()).getJSONArray("data");
        List<SDRKData> sdrkDataList = new ArrayList<>();
        for(Object obj : jsonArray){
            JSONObject json = JSONObject.parseObject(obj.toString());
            String deviceStatus = json.getString("deviceStatus");
            String devAddr = json.getString("deviceAddr");      // 设备序列号
            String time = DATE_TIME_FORMATTER.format(Instant.ofEpochMilli(json.getLong("timeStamp")).atZone(ZoneOffset.ofHours(8)).toLocalDateTime());
            String status = "normal".equals(deviceStatus) ? "1" : "offline".equals(deviceStatus) ? "0" : "alarming".equals(deviceStatus) ? "2" : "3";
            if(CollectionUtils.isNotEmpty(equipmentList)){
                for(Equipment equipment : equipmentList){
                    if(devAddr.equals(equipment.getSerial())){
                        equipment.setStatus(status);
                        break;
                    }
                }
            }
            JSONArray dataItem = json.getJSONArray("dataItem");
            for(Object item : dataItem){
                JSONObject dataItemJson = JSONObject.parseObject(item.toString());
                String registerName = dataItemJson.getString("registerName");
                Float val = dataItemJson.getFloat("data");
                String unit = dataItemJson.getString("unit");

                SDRKData sdrkData = new SDRKData();
                Optional<Equipment> equipment = equipmentList.stream().filter(x -> x.getSerial().equals(devAddr)).findFirst();
                if(equipment.isPresent())
                    sdrkData.setEquipmentId(equipment.get().getId());
                else
                    break;
                sdrkData.setParamUnit(unit);
                sdrkData.setParamVal(val);
                sdrkData.setParamName(registerName);
                sdrkData.setCtime(time);
                sdrkData.setType("7");
                sdrkData.setCompanyId(equipment.get().getCompanyId());
                sdrkDataList.add(sdrkData);
            }
        }
        JSONObject json = new JSONObject();
        json.put("dataList", sdrkDataList);
        json.put("equipmentList", equipmentList);
        return json;
    }



    public static List<DevDTO> getAllDev(String token) {
        Map<String, String> param = new HashMap<>();
        param.put("FunCode", "");
        String result = HttpRequest.post(SJRT_GET_ALL_DEV).body(JSONObject.toJSONString(param))
                .header("Authorization", "Bearer " + token).execute().body();
        boolean isSuccess = JSONObject.parseObject(result).getBoolean("IsSuccess");
        if (isSuccess) {
            return JSONObject.parseArray(JSONObject.parseObject(result).getString("Data"), DevDTO.class);
        } else {
            return new ArrayList<>();
        }
    }

    public static String getVideo(String devId, String token) {
        Map<String, String> param = new HashMap<>();
        param.put("DevId", devId);
        String result = HttpRequest.post(SJRT_GET_VIDEO_URL).body(JSONObject.toJSONString(param))
                .header("Authorization", "Bearer " + token).execute().body();
        boolean isSuccess = JSONObject.parseObject(result).getBoolean("IsSuccess");
        if (isSuccess) {
            return JSONObject.parseObject(result).getString("Data");
        } else {
            throw new BusinessException(JSONObject.parseObject(result).getString("Msg"));
        }
    }

    public static boolean videoMove(String devId, String val, String token) {
        Map<String, String> param = new HashMap<>();
        param.put("DevId", devId);
        param.put("Val", val);
        String result = HttpRequest.post(GetCWDevData.videoMove).body(JSONObject.toJSONString(param))
                .header("Authorization", "Bearer " + token).execute().body();
        boolean isSuccess = JSONObject.parseObject(result).getBoolean("IsSuccess");
        if (isSuccess) {
            return true;
        } else {
            throw new BusinessException(JSONObject.parseObject(result).getString("Msg"));
        }
    }



    // 检验世纪瑞通设备状态
    public static List<DevDTO> getDevState(List<DevDTO> allDev) {
        LocalDateTime now = LocalDateTime.now();
        for (DevDTO devDTO : allDev) {
            Duration dur = null;
            try {
                dur = Duration.between(devDTO.getHeartbeatTime(), now);
            }catch (Exception e){
                devDTO.setState("2");
            }
            if(dur == null){
                devDTO.setState("2");
                continue;
            }
            if ("虫情测报仪".equals(devDTO.getDevType()) || EQU_TYPE_KILL_INSECT.equals(devDTO.getDevType()) || EQU_TYPE_VIDEO.equals(devDTO.getDevType())) {
                if (dur.toMinutes() > 60) {
                    devDTO.setState("2");
                } else {
                    devDTO.setState("1");
                }
            } else {
                if (dur.toMinutes() > 10) {
                    devDTO.setState("2");
                } else {
                    devDTO.setState("1");
                }
            }
        }
        return allDev;
    }






    // 将世纪瑞通返回的设备信息转换成自己平台的 Equipment
    public static List<Equipment> devToEqu(List<DevDTO> allDev, List<Equipment> equipmentList) {
        for(Equipment equipment : equipmentList){
            for(DevDTO devDTO : allDev){
                if(equipment.getSerial().equals(devDTO.getDevId())){
                    equipment.setStatus("2".equals(devDTO.getState()) ? "0" : "1");
                    LocalDateTime heartbeatTime = devDTO.getHeartbeatTime();
                    if(heartbeatTime == null){
                        if("0".equals(equipment.getStatus()))
                            equipment.setHeartbeatTime("无");
                        else
                            equipment.setHeartbeatTime(LocalDateTime.now().minusMinutes(16).format(DATE_TIME_FORMATTER));
                    }
                    equipment.setPurchaseTime(equipment.getHeartbeatTime());
                    break;
                }
            }
        }
        for(Equipment equipment : equipmentList){
            if(StringUtils.isBlank(equipment.getStatus()))
                equipment.setStatus("0");
        }
        return equipmentList;
    }


























}
